import model.backoffice.BackofficeParams
import zio.*
import zio.http.*
import zio.config.typesafe.*
import zio.http.Header.AccessControlAllowOrigin
import zio.http.Middleware.{CorsConfig, cors}
import zio.http.codec.PathCodec

object BackofficeWorker extends ZIOAppDefault {
  private val corsConfig = CorsConfig(
    allowedOrigin = origin => Some(AccessControlAllowOrigin.Specific(origin))
  )

  private val apiVersion = "1"

  override val bootstrap: ZLayer[ZIOAppArgs, Any, Any] =
    Runtime.setConfigProvider(ConfigProvider.fromResourcePath())

  private val pathCodec: PathCodec[String] = string("event-type")

  private val routes =
    // TODO: разрезать routes на несколько роутов и для каждой группы кидать свои ошибки, не везде идет обработка json
    Routes(
      Method.GET / "ping" -> handler(Response.text("pong")),
      Method.GET / "api" / s"v$apiVersion" / pathCodec -> Handler
        .fromFunctionHandler[(String, Request)] { case (eventType: String, req: Request) =>
          val queryParams = List("offset", "period", "filter", "limit")
            .map(param => param -> req.queryParam(param))
            .toMap
          val validatedParams = BackofficeParams.validateParams(queryParams)
          Handler.fromResponseZIO(
            // TODO: обработать неизвестный путь
            Responses.buildResponse(eventType, validatedParams)
          )
        }
    ).handleError { case _ =>
      Response.badRequest("Wrong JSON payload")
    } @@ Middleware.cors(corsConfig)

  def run = Server
    .install(routes)
    .flatMap(port => ZIO.logInfo(s"Sever started on http://localhost:$port") *> ZIO.never)
    .provideLayer(Server.configured() ++ DBService.live)
    .exitCode
}
